﻿using System.Text;
using System.Xml;

namespace InfoPathHelpers.XmlGeneration
{
    public static class XmlGenerator
    {
        public static string Generate(string prefix, string ns, NodeDefinition rootNode)
        {
            var Xml = new StringBuilder();

            var Settings = new XmlWriterSettings() 
            { 
                OmitXmlDeclaration = true, 
                Encoding = UTF8Encoding.UTF8, 
                Indent = true,
                ConformanceLevel = ConformanceLevel.Fragment
            };

            using (var Writer = XmlWriter.Create(Xml, Settings))
            {
                if (rootNode is AttributeDefinition)
                {
                    WriteAttribute(Writer, rootNode as AttributeDefinition, prefix, ns);
                    
                }
                else if (rootNode is ElementDefinition)
                {
                    WriteElement(Writer, rootNode as ElementDefinition, prefix, ns);
                }
                else if (rootNode is GroupDefinition)
                {
                    WriteGroup(Writer, rootNode as GroupDefinition, prefix, ns);
                }
            }

            return Xml.ToString();
        }

        private static void WriteAttribute(XmlWriter writer, AttributeDefinition attribute, string prefix, string ns)
        {
            writer.WriteAttributeString(prefix, attribute.LocalName, ns, attribute.DefaultValue);
        }

        private static void WriteElement(XmlWriter writer, ElementDefinition element, string prefix, string ns)
        {
            writer.WriteStartElement(prefix, element.LocalName, ns);
            writer.WriteValue(element.DefaultValue);
            foreach (var Attribute in element.Attributes)
            {
                WriteAttribute(writer, Attribute, prefix, ns);
            }
            writer.WriteEndElement();
        }

        private static void WriteGroup(XmlWriter writer, GroupDefinition group, string prefix, string ns)
        {
            writer.WriteStartElement(prefix, group.LocalName, ns);
            foreach (var Attribute in group.Attributes)
            {
                WriteAttribute(writer, Attribute, prefix, ns);
            }
            foreach (var Element in group.Elements)
            {
                if(Element is ElementDefinition)
                {
                    WriteElement(writer, Element as ElementDefinition, prefix, ns);
                }
                else if(Element is GroupDefinition)
                {
                    WriteGroup(writer, Element as GroupDefinition, prefix, ns);
                }
            }

            writer.WriteEndElement();
        }
    }
}
